//#define DEBUG_LOGGER
#include "CLogger.h"
//
// this is a yabo(r) trick to ensure
// the singleton destruction on
// program termination
//
class CLoggerCleaner
{
public:
    ~CLoggerCleaner()
    {
        CLogger::Destroy();
#ifdef DEBUG_LOGGER
        std::cout << "CLoggerCleaner::~CLoggerCleaner() : class destuctor called"
        << std::endl;
#endif
    }

}CLoggerInst;

CLogger* CLogger::_instance = 0;
int CLogger::_refCount = 0;

CLogger::CLogger() : nLogEvent(0)
{
#ifdef DEBUG_LOGGER
    std::cout << "CLogger::CLogger() : class constructor called" << std::endl;
    //Ctor
#endif
}

/*
CLogger::~CLogger()
{
    std::cout << "CLogger::~CLogger() : class destructor called" << std::endl;
    //Dtor
}
*/

CLogger* CLogger::Instance()
{
    if ( _instance == 0 ) // if first time ...
    {
        _instance = new CLogger(); // ... create a new 'solo' instance
#ifdef DEBUG_LOGGER
        std::cout << "CLogger::Instance() : _instance created" << std::endl;
#endif
    }
    _refCount++; //increase reference counter
#ifdef DEBUG_LOGGER
    std::cout << "CLogger::Instance() : _refCount = " << _refCount << std::endl;
#endif
    return _instance;
}

void CLogger::Release()
{
    if ( --_refCount < 1 )
    {
        Destroy();
#ifdef DEBUG_LOGGER
        std::cout << "CLogger::Release()" << std::endl;
#endif
    }
}

void CLogger::Destroy()
{
    if ( _instance != 0 )
    {
        delete( _instance );
        _instance = 0;
#ifdef DEBUG_LOGGER
        std::cout << "CLogger::Destroy() : _instance deleted" << std::endl;
#endif
    }
}


void CLogger::log(int nLogLevel, char * format, ...)
{
    char buffer[256];
    va_list li;

    va_start(li,format);
    vsprintf(buffer, format, li);
    va_end(li);

    switch (nLogLevel)
    {
    case LOG_LEVEL_CRITICAL:
        std::cerr << "CRITICAL: ";
        std::cerr   << "(" << ++nLogEvent <<") ["
        << " " << buffer <<" ]" <<std::endl;
        break;
    case LOG_LEVEL_DEBUG:
        std::cout << "DEBUG: ";
        std::cout   << "(" << ++nLogEvent <<") ["
        << " " << buffer <<" ]" <<std::endl;
        break;
    case LOG_LEVEL_ERROR:
        std::cerr << "ERROR: ";
        std::cerr   << "(" << ++nLogEvent <<") ["
        << " " << buffer <<" ]" <<std::endl;
        break;
    case LOG_LEVEL_NOTICE:
        std::cout << "NOTICE: ";
        std::cout   << "(" << ++nLogEvent <<") ["
        << " " << buffer <<" ]" <<std::endl;
        break;
    case LOG_LEVEL_WARN:
        std::cout << "WARNING: ";
        std::cout   << "(" << ++nLogEvent <<") ["
        << " " << buffer <<" ]" <<std::endl;
        break;
    default:
        break;
    }
}
